from gmssl import sm3, func

def generate_salt(length=64):
    """生成指定长度的随机盐（十六进制字符串）"""
    # 生成32字节的盐值，即64个十六进制字符
    return func.random_hex(length)

def hash_with_salt(password, salt):
    """使用盐值对密码进行SM3哈希处理"""
    # 将密码和盐拼接起来，并编码为字节
    data = (password + salt).encode('utf-8')
    # 使用SM3算法计算哈希
    hash_value = sm3.sm3_hash(func.bytes_to_list(data))
    # 返回十六进制字符串形式的哈希值
    return hash_value

def verify_password(input_password, salt, stored_hash):
    """验证输入的密码是否与存储的哈希匹配"""
    # 使用相同的盐值对输入密码进行哈希处理
    input_hash = hash_with_salt(input_password, salt)
    # 比较新生成的哈希与存储的哈希
    # 使用常量时间比较防止计时攻击
    return constant_time_compare(input_hash, stored_hash)

def constant_time_compare(val1, val2):
    """进行常量时间比较，防止计时攻击"""
    if len(val1) != len(val2):
        return False
    result = 0
    for x, y in zip(val1, val2):
        result |= ord(x) ^ ord(y)
    return result == 0

# # 示例
# username = "张三"
# pwd = "123456"
# salt = generate_salt()
# pwd_salt_hash = hash_with_salt(pwd, salt)
# print(f"Salt: {salt}")
# print(f"Hashed Password: {pwd_salt_hash}")
#
# # 验证
# is_valid = verify_password("123456", salt, pwd_salt_hash)
# print("Password is valid:", is_valid)